﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;

namespace ImageProcessingLibrary
{
    public class Histogram : List<double>
    {
        #region Public methods
        public Histogram(int numberOfElements)
        {
            for (int i = 0; i < numberOfElements; i++)
            {
                this.Add(0.0);
            }
        }

        public void MakeCumulative()
        {
            Histogram cumulativeHistogram = new Histogram(this.Count);
            cumulativeHistogram[0] = this[0];
            for (int i = 1; i < this.Count; i++)
            {
                cumulativeHistogram[i] = cumulativeHistogram[i - 1] + this[i];
            }
            for (int i = 0; i < this.Count; i++)
            {
                this[i] = cumulativeHistogram[i];
            }
        }

        public void Normalize()
        {
            double sum = this.Sum();
            for (int i = 0; i < this.Count; i++)
            {
                this[i] /= sum;
            }
        }

        public int GetMaximumLevelBin(int minRange, int maxRange)
        {
            double maxLevel = this[minRange];
            int maxLevelBin = minRange;
            for (int ii = minRange + 1; ii <= maxRange; ii++)
            {
                if (this[ii] > maxLevel)
                {
                    maxLevel = this[ii];
                    maxLevelBin = ii;
                }
            }
            return maxLevelBin;
        }

        public Histogram GenerateCumulativeHistogram()
        {
            Histogram cumulativeHistogram = new Histogram(this.Count);
            cumulativeHistogram[0] = this[0];
            for (int i = 1; i < this.Count; i++)
            {
                cumulativeHistogram[i] = cumulativeHistogram[i - 1] + this[i];
            }
            return cumulativeHistogram;
        }

        public Histogram GenerateNormalizedCumulativeHistogram()
        {
            Histogram normalizedCumulativeHistogram = GenerateCumulativeHistogram();
            double sum = normalizedCumulativeHistogram.Sum();
            for (int i = 0; i < this.Count; i++)
            {
                normalizedCumulativeHistogram[i] /= sum;
            }
            return normalizedCumulativeHistogram;
        }

        public Bitmap Plot(Color plotColor, int width, int height)
        {
            Bitmap plotBitmap = new Bitmap(width, height);
            Graphics plotGraphics = Graphics.FromImage(plotBitmap);
            SolidBrush brush = new SolidBrush(Color.Black);
            plotGraphics.FillRectangle(brush, 0.0f, 0.0f, (float)width, (float)height);
            Pen pen = new Pen(plotColor);

            double maxValue = this.Max();
            double xScale = width / (double)this.Count;
            double yScale = height / maxValue;

            for (int i = 0; i < this.Count; i++)
            {
                float xPlot = (float)Math.Round(i * xScale);
                float yPlot = (float)height - (float)Math.Round(this[i] * yScale);
                plotGraphics.DrawLine(pen, xPlot, (float)height, xPlot, yPlot);
            }
            return plotBitmap;
        }
        #endregion
    }
}
